home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / demos / OpenGL / space / sound.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  7KB  |  241 lines

  1. /*
  2.  * Copyright (C) 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <stdio.h>
  18. #include <fcntl.h>
  19. #ifdef SOUND
  20. #include <audio.h>
  21. #endif
  22. #include <GL/gl.h>
  23. #include "space.h"
  24.  
  25. #define CHUNK_ID          4
  26. #define CHUNK_HEADER      8
  27. #define FORM_CHUNK       12
  28. #define FORM_CHUNK_DATA   4
  29. #define COMM_CHUNK       26  /* including the header */
  30. #define COMM_CHUNK_DATA  18
  31. #define SSND_CHUNK       16  /* including the header */
  32. #define SSND_CHUNK_DATA   8
  33.  
  34. typedef struct {
  35.     schar8 id[4];
  36.     uint32 size;
  37.     uint32 nchannels;
  38.     uint32 nsampframes;
  39.     uint32 sampwidth;
  40.     uint32 samprate;
  41. } comm_chunk_t;
  42.  
  43. typedef struct {
  44.     uint32 offset;
  45.     uint32 blocksize;
  46.     uint32 file_position;  /* not in AIFF file */
  47.     uint32 sample_bytes;   /* not in AIFF file */
  48. } ssnd_chunk_t;
  49.  
  50. typedef struct {
  51.     uint32 leftover_bytes;
  52.     uint32 leftover_samps;
  53.     uint32 leftover_frames;
  54.     uint32 bytes_per_buf;
  55.     uint32 samps_per_buf;
  56.     uint32 bytes_per_samp;
  57.     uint32 num_bufs;
  58. } play_t;
  59.  
  60. #ifdef SOUND
  61. static ALport        audio_port;
  62. static schar8        sampbuf[2*2*48000];
  63. #endif
  64.  
  65. static sint32        fd;
  66. static comm_chunk_t  comm_data;
  67. static ssnd_chunk_t  ssnd_data;
  68. static play_t        play;
  69.  
  70. /********************************************************************** 
  71. *  sound_effect()  -  
  72. **********************************************************************/
  73. void sound_effect(schar8 *soundfile)
  74.  
  75. {  uchar8   buf[32];
  76.    sint32   n,pvbuf[2];
  77. #ifdef SOUND
  78.    ALconfig audio_port_config;
  79.     
  80.    if ((fd = open(soundfile, O_RDONLY)) < 0)
  81.      exit(0);
  82.  
  83.    if (read(fd, buf, CHUNK_HEADER) != CHUNK_HEADER)
  84.      exit(0) ;
  85.  
  86.    comm_data.id[0] = buf[0];
  87.    comm_data.id[1] = buf[1];
  88.    comm_data.id[2] = buf[2];
  89.    comm_data.id[3] = buf[3];
  90.    comm_data.size = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7] ;
  91.  
  92.    if (strncmp(comm_data.id, "FORM", 4) || comm_data.size <= 0)
  93.      exit(0);
  94.  
  95.    if (read(fd, buf, FORM_CHUNK_DATA) != FORM_CHUNK_DATA) 
  96.      exit(0);
  97.  
  98.    /* loop on the local chunks */
  99.    while ((n = read(fd, buf, CHUNK_HEADER)) != 0)  {
  100.      if (n != CHUNK_HEADER)
  101.        exit(0);
  102.  
  103.      comm_data.id[0] = buf[0];
  104.      comm_data.id[1] = buf[1];
  105.      comm_data.id[2] = buf[2];
  106.      comm_data.id[3] = buf[3];
  107.      comm_data.size = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7] ;
  108.  
  109.      if (!strncmp(comm_data.id, "COMM", 4))  {  /* common */
  110.        if (read(fd, buf, COMM_CHUNK_DATA) != COMM_CHUNK_DATA)
  111.          exit(0);
  112.  
  113.        comm_data.nchannels   = (buf[0]<<8) | buf[1] ;
  114.        comm_data.nsampframes = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5] ;
  115.        comm_data.sampwidth   = (buf[6]<< 8) | buf[7] ;
  116.        comm_data.samprate    = (buf[10]<<8) | buf[11] ;
  117.        }
  118.  
  119.      else if (!strncmp(comm_data.id, "SSND", 4))  {  /* sound data */
  120.        if (read(fd, buf, SSND_CHUNK_DATA) != SSND_CHUNK_DATA)
  121.          exit(0) ;
  122.  
  123.        ssnd_data.offset    = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3] ;
  124.        ssnd_data.blocksize = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7] ;
  125.  
  126.        ssnd_data.file_position = lseek(fd, 0, SEEK_CUR);
  127.        ssnd_data.sample_bytes  = comm_data.size - 8;
  128.        lseek(fd, ssnd_data.sample_bytes, SEEK_CUR);
  129.        }
  130.  
  131.      else if ((!strncmp(comm_data.id, "MARK", 4))  /* marker */
  132.            || (!strncmp(comm_data.id, "INST", 4))  /* instrument */
  133.            || (!strncmp(comm_data.id, "APPL", 4))  /* appl specific */
  134.            || (!strncmp(comm_data.id, "MIDI", 4))  /* midi data */
  135.            || (!strncmp(comm_data.id, "AESD", 4))  /* audio  rec */
  136.            || (!strncmp(comm_data.id, "COMT", 4))  /* comments */
  137.            || (!strncmp(comm_data.id, "NAME", 4))  /* text */
  138.            || (!strncmp(comm_data.id, "AUTH", 4))  /* text */
  139.            || (!strncmp(comm_data.id, "(c) ", 4))  /* text */
  140.            || (!strncmp(comm_data.id, "ANNO", 4))) /* text */   {
  141.        lseek(fd, comm_data.size, SEEK_CUR);
  142.        }
  143.  
  144.      else exit(0) ;
  145.      } 
  146.  
  147.    /* set output sample rate */
  148.    pvbuf[0] = AL_OUTPUT_RATE;
  149.    pvbuf[1] = comm_data.samprate;
  150.    ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2);
  151.  
  152.    /* configure and open audio port */
  153.    audio_port_config = ALnewconfig();
  154.    ALsetwidth(audio_port_config, comm_data.sampwidth>>3);
  155.    ALsetchannels(audio_port_config, comm_data.nchannels);
  156.    audio_port = ALopenport("space", "w", audio_port_config);
  157.  
  158.    /* make the buffer large enough to hold 1/2 sec of audio frames */
  159.    play.bytes_per_samp  = comm_data.sampwidth>>3;
  160.    play.bytes_per_buf   = play.bytes_per_samp * comm_data.nchannels * comm_data.samprate / 2;
  161.    play.samps_per_buf   = play.bytes_per_buf / play.bytes_per_samp;
  162.    play.leftover_bytes  = ssnd_data.sample_bytes % play.bytes_per_buf;
  163.    play.leftover_samps  = play.leftover_bytes / play.bytes_per_samp;
  164.    play.leftover_frames = play.leftover_samps / comm_data.nchannels;
  165.    play.num_bufs        = ssnd_data.sample_bytes / play.bytes_per_buf;
  166.  
  167.    play_file();
  168.  
  169. /*
  170.    for (n=400; n>0; n--)
  171.      play_sample(n) ;
  172. */
  173. #endif
  174. }
  175.  
  176. /********************************************************************** 
  177. *  play_file()  -  
  178. **********************************************************************/
  179. static void play_file(void)
  180.  
  181. {  register sint32 i;
  182.  
  183. #ifdef SOUND
  184.    /* move the fileptr to the beginning of the sample data */
  185.    lseek(fd, ssnd_data.file_position, SEEK_SET);
  186.  
  187.    for (i=0; i<play.num_bufs; i++) {
  188.      read(fd, sampbuf, play.bytes_per_buf);
  189.      ALwritesamps(audio_port, sampbuf, play.samps_per_buf);
  190.      }
  191.  
  192.    read(fd, sampbuf, play.leftover_bytes);
  193.    ALwritesamps(audio_port, sampbuf, play.leftover_samps);
  194.  
  195.    while (ALgetfilled(audio_port) > 0)
  196.      sginap(1);
  197. #endif
  198. }
  199.  
  200. /********************************************************************** 
  201. *  play_sample()  -  
  202. **********************************************************************/
  203. static void play_sample(uint32 index)
  204.  
  205. {  uint32 pos = ssnd_data.file_position + index*play.bytes_per_buf ;
  206.   
  207. #ifdef SOUND
  208.    lseek(fd, pos, SEEK_SET);
  209.  
  210.    if (index < play.num_bufs)  {
  211.      read(fd, sampbuf, play.bytes_per_buf);
  212. reverse_buffer(sampbuf) ;
  213.      ALwritesamps(audio_port, sampbuf, play.samps_per_buf);
  214.      }
  215.    else  {
  216.      read(fd, sampbuf, play.leftover_bytes);
  217.      ALwritesamps(audio_port, sampbuf, play.leftover_samps);
  218.      }
  219. #endif
  220. }
  221.  
  222. /********************************************************************** 
  223. *  reverse_buffer()  - 
  224. **********************************************************************/
  225. static void reverse_buffer(uchar8 *buf)
  226.  
  227. {  register uint16 *s1, *s2, tmp ;
  228.    register uint32 i,count ;
  229.  
  230.    s1 = (uint16 *)buf ;
  231.    s2 = (uint16 *) (uchar8 *) (buf + play.bytes_per_buf - 4);
  232.    count = play.bytes_per_buf >> 3 ;
  233.  
  234.    for (i=0; i<count; s1++,s2--,i++)  {
  235.      tmp = *s1 ;
  236.      *s1 = *s2 ;
  237.      *s2 = tmp ;
  238.      }
  239. }
  240.  
  241.